﻿using System.Threading.Tasks;
using Bit.Admin.Models;
using Bit.Core.Identity;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;

namespace Bit.Admin.Controllers
{
    public class LoginController : Controller
    {
        private readonly PasswordlessSignInManager<IdentityUser> _signInManager;

        public LoginController(
            PasswordlessSignInManager<IdentityUser> signInManager)
        {
            _signInManager = signInManager;
        }

        public IActionResult Index(string returnUrl = null, int? error = null, int? success = null,
            bool accessDenied = false)
        {
            if (!error.HasValue && accessDenied)
            {
                error = 4;
            }

            return View(new LoginModel
            {
                ReturnUrl = returnUrl,
                Error = GetMessage(error),
                Success = GetMessage(success)
            });
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Index(LoginModel model)
        {
            if (ModelState.IsValid)
            {
                await _signInManager.PasswordlessSignInAsync(model.Email, model.ReturnUrl);
                return RedirectToAction("Index", new
                {
                    success = 3
                });
            }

            return View(model);
        }

        public async Task<IActionResult> Confirm(string email, string token, string returnUrl)
        {
            var result = await _signInManager.PasswordlessSignInAsync(email, token, true);
            if (!result.Succeeded)
            {
                return RedirectToAction("Index", new
                {
                    error = 2
                });
            }

            if (!string.IsNullOrWhiteSpace(returnUrl) && Url.IsLocalUrl(returnUrl))
            {
                return Redirect(returnUrl);
            }

            return RedirectToAction("Index", "Home");
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Logout()
        {
            await _signInManager.SignOutAsync();
            return RedirectToAction("Index", new
            {
                success = 1
            });
        }

        private string GetMessage(int? messageCode)
        {
            return messageCode switch
            {
                1 => "You have been logged out.",
                2 => "This login confirmation link is invalid. Try logging in again.",
                3 => "If a valid admin user with this email address exists, " +
                    "we've sent you an email with a secure link to log in.",
                4 => "Access denied. Please log in.",
                _ => null,
            };
        }
    }
}
